Skip to content

feat: support np.random.Generator#3983

Open
flying-sheep wants to merge 12 commits intomainfrom
pa/rng
Open

feat: support np.random.Generator#3983
flying-sheep wants to merge 12 commits intomainfrom
pa/rng

Conversation

@flying-sheep
Copy link
Member

@flying-sheep flying-sheep commented Feb 23, 2026

The idea is to make the code behave as closely as possible to how it did, but make it read like modern code:

  1. add decorator that converts random_state into rng argument (deduplicating them and using 0 by default)
  2. add helpers that allow old behavior (e.g. for APIs that only take RandomState)
    • _FakeRandomGen.wrap_global and _if_legacy_apply_global to conditionally replace np.random.seed and other global-state-mutating functions
    • legacy_random_state to get back a random_state argument for APIs that don’t take rng, e.g. scikit-learn stuff and "random_state" in adata.uns[thing]["params"]
  3. after this PR: make feat: presets #3653 change the default behavior when a preset is passed.

TODO:

  • add the decorator
  • add helpers for restarting (e.g. if 0 was passed, it’d be reused by the functions called in function body)
  • for the functions that called it: re-add the np.random.seed calls (maybe if isinstance(rng, _FakeRandomGen): gen = legacy_numpy_gen(rng) or so?)
    • partially done, finish the work
  • add spawn to _FakeRandomGen (that does nothing) and use spawn for a tree structure
  • figure out how to handle persistence for new RNG (random_state in adata.uns[thing]["params"])
  • pass rng to neighbors transformer?

@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

❌ Patch coverage is 86.62420% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.97%. Comparing base (af57cff) to head (1e43b2a).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/scanpy/_utils/random.py 80.39% 10 Missing ⚠️
src/scanpy/tools/_draw_graph.py 64.28% 5 Missing ⚠️
src/scanpy/neighbors/__init__.py 80.00% 2 Missing ⚠️
src/scanpy/preprocessing/_pca/__init__.py 77.77% 2 Missing ⚠️
src/scanpy/experimental/pp/_normalization.py 66.66% 1 Missing ⚠️
src/scanpy/experimental/pp/_recipes.py 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3983      +/-   ##
==========================================
- Coverage   77.96%   76.97%   -0.99%     
==========================================
  Files         118      118              
  Lines       12517    12592      +75     
==========================================
- Hits         9759     9693      -66     
- Misses       2758     2899     +141     
Flag Coverage Δ
hatch-test.low-vers ?
hatch-test.pre 76.97% <86.62%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/scanpy/datasets/_datasets.py 91.05% <100.00%> (+0.14%) ⬆️
src/scanpy/experimental/_docs.py 100.00% <ø> (ø)
src/scanpy/preprocessing/_deprecated/sampling.py 100.00% <100.00%> (ø)
src/scanpy/preprocessing/_pca/_compat.py 100.00% <100.00%> (ø)
src/scanpy/preprocessing/_recipes.py 91.07% <100.00%> (+0.33%) ⬆️
src/scanpy/preprocessing/_scrublet/__init__.py 96.90% <100.00%> (+0.16%) ⬆️
src/scanpy/preprocessing/_scrublet/core.py 92.66% <100.00%> (-0.05%) ⬇️
src/scanpy/preprocessing/_scrublet/pipeline.py 90.00% <100.00%> (+0.25%) ⬆️
src/scanpy/preprocessing/_scrublet/sparse_utils.py 88.46% <100.00%> (-0.83%) ⬇️
src/scanpy/preprocessing/_simple.py 91.01% <100.00%> (+0.27%) ⬆️
... and 16 more

... and 6 files with indirect coverage changes

@flying-sheep flying-sheep added this to the 1.13.0 milestone Feb 26, 2026
@flying-sheep flying-sheep marked this pull request as ready for review February 26, 2026 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Switch to numpy.random.Generator

1 participant